package net.mayee.alice.web.controller.admin.profile;

import jodd.props.Props;
import net.mayee.alice.common.Definiens;
import net.mayee.alice.entity.admin.account.User;
import net.mayee.alice.filter.ShiroAdminDbRealm;
import net.mayee.alice.web.controller.base.BaseController;
import net.mayee.common.AliceHelper;
import net.mayee.common.utils.Encodes;
import net.mayee.leo.LeoEncrypt;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.IOException;
import java.math.BigInteger;

@Controller
public class LockScreenController extends BaseController {

    @RequiresUser
    @RequestMapping(value = "/sdm/prof/lockS")
    public String lockS(Model model) {
        Props props = AliceHelper.getInstance().getJoddProps();

        Subject currentUser = SecurityUtils.getSubject();
        ShiroAdminDbRealm.ShiroUser shiroUser = (ShiroAdminDbRealm.ShiroUser) currentUser.getPrincipal();
        shiroUser.setIsLockScreen(Definiens.STATUS_CODE_LOCKSCREEN);

        model.addAttribute("rsa_modulus", props.getValue("encrypt.rsa.modulus"));
        model.addAttribute("rsa_exponent", props.getValue("encrypt.rsa.public.exponent"));
        return "profile/me/lockScreen";
    }

    @RequiresUser
    @RequestMapping(value = "/doUnLockScreen", method = RequestMethod.POST)
    public String doUnLockScreen(@RequestParam("password") String password, ModelMap model)
            throws IOException {
        String failMsg = null;
        Props props = AliceHelper.getInstance().getJoddProps();

        /* decrypt password */
        String privateExponent = props.getValue("encrypt.rsa.private.exponent");
        String modulus = props.getValue("encrypt.rsa.modulus");

        byte[] de_password = null;
        try {
            de_password = LeoEncrypt.easyDecryptRSAByProviderPirvateKey(
                    modulus,
                    privateExponent,
                    new org.bouncycastle.jce.provider.BouncyCastleProvider(),
                    new BigInteger(password, 16).toByteArray()
            );
        } catch (Exception e) {
            e.printStackTrace();
        }

        Subject currentUser = SecurityUtils.getSubject();
        ShiroAdminDbRealm.ShiroUser shiroUser = (ShiroAdminDbRealm.ShiroUser) currentUser.getPrincipal();

        User user = this.getUserService().getUser(shiroUser.getUuid());
        if (user != null) {
            try {
                String pw = StringUtils.reverse(new String(de_password));
                String inputPWByHex = Encodes.encodeHex(
                        LeoEncrypt.sha1(
                                pw.getBytes(),
                                Encodes.decodeHex(user.getSalt()),
                                Integer.parseInt(props.getValue("encrypt.hash.interations"))
                        )
                );
                if(user.getLoginPassword().equals(inputPWByHex)){
                    shiroUser.setIsLockScreen(Definiens.STATUS_CODE_UNLOCKSCREEN);
                }else{
                    failMsg = this.getMessage("net.mayee.alice.login.msg.lockscreen_error", "密码错误,请重新登录!");
                }
            } catch (Exception e) {
                failMsg = this.getMessage("net.mayee.alice.login.msg.login_error", "登陆异常！");
                e.printStackTrace();
            }
        }else{
            failMsg = this.getMessage("net.mayee.alice.login.msg.login_error", "登陆异常！");
        }

        /* 只要错一次,就强制登出,重新登录 */
        if (failMsg != null) {
            SecurityUtils.getSubject().logout();
            model.addAttribute(
                    FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME, failMsg);
            return "forward:/login";
        }

        return "redirect:/sdm/main";
    }

}
